package basic_grammar

import "fmt"

// 接口
// 面向接口编程
// 体现面向对象多态特性
// 隐式实现

type Mobile interface {
	Call(telNum string)
	Connect5G()
}

type XiaoMi struct {
	Brand string
}

func (x XiaoMi) Call(telNum string) {
	fmt.Printf("%s拨打电话%s\n", x.Brand, telNum)
}

func (x XiaoMi) Connect5G() {
	fmt.Printf("%s连接5G网络\n", x.Brand)
}

type HuaWei struct {
	Brand string
}

func (h HuaWei) Call(telNum string) {
	fmt.Printf("%s拨打电话%s\n", h.Brand, telNum)
}

func (h HuaWei) Connect5G() {
	fmt.Printf("%s连接5G网络\n", h.Brand)
}

func TestInterface() {
	x := XiaoMi{"小米"}
	useMobile(x)
	h := HuaWei{"华为"}
	useMobile(h)

	mobiles := []Mobile{x, h}

	fmt.Println(mobiles)
	mobiles[0].Call("19281019281")

}

func useMobile(mobile Mobile) {
	mobile.Connect5G()
	mobile.Call("13578909821")
}

func (h HuaWei) leicaPhoto() {
	fmt.Printf("%s用徕卡认证镜头拍了一张照片\n", h.Brand)
}

func (x XiaoMi) px100MillionPhoto() {
	fmt.Printf("%s用一亿像素的相机拍照\n", x.Brand)
}

func TestTypeAssert() {
	x := XiaoMi{"小米"}
	h := HuaWei{"华为"}
	//testXiaoMiPhoto(x)
	//testHuaWeiPhoto(h)
	//testXiaoMiPhoto(h)
	//testHuaWeiPhoto(x)
	//testMobile(x)
	//testMobile(h)

	switchTypeAssert(x)
	switchTypeAssert(h)
	switchTypeAssert(Integer(100))
	switchTypeAssert(34)
}

func testXiaoMiPhoto(m Mobile) {
	a := m.(XiaoMi)
	a.px100MillionPhoto()
}

func testHuaWeiPhoto(mobile Mobile) {
	a := mobile.(HuaWei)
	a.leicaPhoto()
}

func testMobile(mobile Mobile) {
	if m, ok := mobile.(XiaoMi); ok {
		m.px100MillionPhoto()
	} else if m, ok := mobile.(HuaWei); ok {
		m.leicaPhoto()
	}
}

// 空接口
// interface{}
// 相当于面向对象的Object类
// 类型断言

func switchTypeAssert(m interface{}) {
	switch m.(type) {
	case HuaWei:
		p := m.(HuaWei)
		p.leicaPhoto()
	case XiaoMi:
		p := m.(XiaoMi)
		p.px100MillionPhoto()
	case Integer:
		p := m.(Integer)
		if p.isEven() {
			fmt.Println("我是偶数")
		} else {
			fmt.Println("我是奇数")
		}
	default:
		fmt.Println("啥也不是～～～～～～～")
	}
}
